#pragma once
#include <LibraryConfig.hpp>

#ifdef ZZZ_LIB_DEVIL
#include <IL/ilut.h>  // Probably only have to #include this one

class ILImage
{
public:
  ILImage();
  ILImage(const char *);
  ILImage(const ILImage &);
  virtual    ~ILImage();

  ILboolean  Load(const char *);
  ILboolean  Load(const char *, ILenum);
  ILboolean  Save(const char *, bool overwrite=true);
  ILboolean  Save(const char *, ILenum, bool overwrite=true);

  // ImageLib functions
  ILboolean  ActiveImage(ILuint);
  ILboolean  ActiveLayer(ILuint);
  ILboolean  ActiveMipmap(ILuint);
  ILboolean  Clear(void);
  void    ClearColour(ILclampf, ILclampf, ILclampf, ILclampf);
  ILboolean  Convert(ILenum NewFormat, ILenum NewType=IL_UNSIGNED_BYTE);
  ILboolean  Copy(ILuint);
  ILboolean  Default(void);
  ILboolean  Flip(void);
  ILboolean  SwapColours(void);
  ILboolean  Resize(ILuint, ILuint, ILuint);
  ILboolean  TexImage(ILuint, ILuint, ILuint, ILubyte, ILenum, ILenum, void*);

  // Image handling
  void    Bind(void) const;
  void    Bind(ILuint);
  void    Close(void) { this->Delete(); }
  void    Delete(void);
  void    iGenBind();
  ILenum    PaletteAlphaIndex();

  // Image characteristics
  ILuint    Width(void);
  ILuint    Height(void);
  ILuint    Depth(void);
  ILubyte    Bpp(void);
  ILubyte    Bitpp(void);
  ILenum    PaletteType(void);
  ILenum    Format(void);
  ILenum    Type(void);
  ILuint    NumImages(void);
  ILuint    NumMipmaps(void);
  ILuint    GetId(void) const;
  ILenum      GetOrigin(void);
  ILubyte    *GetData(void);
  ILubyte    *GetPalette(void);

  // Rendering
  ILuint    BindImage(void);
  ILuint    BindImage(ILenum);

  // Operators
  ILImage&  operator = (ILuint);
  ILImage&  operator = (const ILImage &);

protected:
  ILuint    Id;
private:
  static void    iStartUp();
};


class ILFilters
{
public:
  static ILboolean  Alienify(ILImage &);
  static ILboolean  BlurAvg(ILImage &, ILuint Iter);
  static ILboolean  BlurGaussian(ILImage &, ILuint Iter);
  static ILboolean  Contrast(ILImage &, ILfloat Contrast);
  static ILboolean  EdgeDetectE(ILImage &);
  static ILboolean  EdgeDetectP(ILImage &);
  static ILboolean  EdgeDetectS(ILImage &);
  static ILboolean  Emboss(ILImage &);
  static ILboolean  Gamma(ILImage &, ILfloat Gamma);
  static ILboolean  Negative(ILImage &);
  static ILboolean  Noisify(ILImage &, ILubyte Factor);
  static ILboolean  Pixelize(ILImage &, ILuint PixSize);
  static ILboolean  Saturate(ILImage &, ILfloat Saturation);
  static ILboolean  Saturate(ILImage &, ILfloat r, ILfloat g, ILfloat b, ILfloat Saturation);
  static ILboolean  ScaleColours(ILImage &, ILfloat r, ILfloat g, ILfloat b);
  static ILboolean  Sharpen(ILImage &, ILfloat Factor, ILuint Iter);
};


//class ILOpenGL
//{
//public:
//  static void    Init(void);
//  static GLuint    BindTex(ILImage &);
//  static ILboolean  Upload(ILImage &, ILuint);
//  static GLuint    Mipmap(ILImage &);
//  static ILboolean  Screen(void);
//  static ILboolean  Screenie(void);
//  static void      DrawImage(ILImage &);
//};

class ILValidate
{
public:
  static ILboolean  Valid(ILenum, char *);
  static ILboolean  Valid(ILenum, FILE *);
  static ILboolean  Valid(ILenum, void *, ILuint);
};


class ILState
{
public:
  static ILboolean    Disable(ILenum);
  static ILboolean    Enable(ILenum);
  static void      Get(ILenum, ILboolean &);
  static void      Get(ILenum, ILint &);
  static ILboolean    GetBool(ILenum);
  static ILint      GetInt(ILenum);
  static const char    *GetString(ILenum);
  static ILboolean    IsDisabled(ILenum);
  static ILboolean    IsEnabled(ILenum);
  static ILboolean    Origin(ILenum);
  static void      Pop(void);
  static void      Push(ILuint);
};


class ILError
{
public:
  static void    Check(void (*Callback)(const char *));
  static void    Check(void (*Callback)(ILenum));
  static ILenum    Get(void);
  static const char  *String(void);
  static const char  *String(ILenum);
};
#endif // ZZZ_LIB_DEVIL
